#include "client.h"
/* #include <sys/sendfile.h> */

int sendMessageToServer(int fd, char *buf, int length) {
    train_t train;
    memset(&train, 0, sizeof(train));
    train.length = length;
    memcpy(train.data, buf, length);
    ssize_t sendRet = send(fd, &train, sizeof(train.length) + length, 0);
    ERROR_CHECK(sendRet, -1, "send");
    return 0;
}

int sendFileToServer(int fd, char *localPath, char *virtualPath) {
    /*文件名*/
    train_t train;
    train.length = strlen(virtualPath);
    memcpy(train.data,virtualPath,train.length);
    send(fd,&train,sizeof(train.length)+train.length,MSG_NOSIGNAL);
    /*文件哈希值*/
    char md5[128];
    changeToMd5(localPath,md5);
    train.length=strlen(md5);
    memcpy(train.data,md5,train.length);
    send(fd,&train,sizeof(train.length)+train.length,MSG_NOSIGNAL);
    /*文件长度*/
    int filefd = open(localPath,O_RDWR);
    ERROR_CHECK(filefd,-1,"filefd");
    struct stat statbuf;
    fstat(filefd,&statbuf);
    printf("%d\n",(int)statbuf.st_size);
    train.length = sizeof(statbuf.st_size);
    memcpy(train.data,&statbuf.st_size,train.length);
    send(fd,&train,sizeof(train.length)+train.length,MSG_NOSIGNAL);
    // ftruncate(fd,statbuf.st_size);
    // char *p = (char *)mmap(NULL,statbuf.st_size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
     //send(netfd,p,statbuf.st_size,MSG_NOSIGNAL);
    // munmap(p,statbuf.st_size);
    /*文件*/
    sendfile(fd,filefd,NULL,statbuf.st_size);

    close(filefd);
    
    return 0;
}

int recvn(int sockfd, void *buf, int length){
    int total = 0; //已经收到的总长度
    char *p = (char *)buf;
    while(total < length){
        ssize_t sret = recv(sockfd,p+total,length-total,0);
        total += sret;
    }
    return 0;
}

int recvFileFromServer(int fd) {
    
    /*文件名*/
    train_t train;
    recvn(fd,&train.length,sizeof(train.length));
    recvn(fd,train.data,train.length);
    char filename[4096] = {0};
    memcpy(filename,train.data,train.length);

    /*文件哈希值*/
    /* recvn(fd,&train.length,sizeof(train.length)); */
    /* recvn(fd,train.data,train.length); */
    /* char md5[128]; */
    /* memcpy(md5,train.data,train.length); */
    /* printf("md5=%s",md5); */

    int filefd = open(filename,O_RDWR|O_CREAT,0666);
    off_t offset=lseek(filefd,0,SEEK_END);
    send(fd,&offset,sizeof(offset),0);

    off_t filesize;
    recvn(fd,&train.length,sizeof(train.length));
    recvn(fd,train.data,train.length);
    memcpy(&filesize,train.data,sizeof(filesize));
    ftruncate(filefd,filesize);
    /*文件*/
    char *p = (char *)mmap(NULL,filesize,PROT_READ|PROT_WRITE,MAP_SHARED,filefd,0);
    recvn(fd,p + offset,filesize-offset);

    munmap(p,filesize);
    close(filefd);
    return 0;
}

ssize_t recvStdin(char *buf, int bufLength) {
    memset(buf, 0, bufLength);
    ssize_t rdRet = read(STDIN_FILENO, buf, bufLength);
    ERROR_CHECK(rdRet, -1, "read");
    return rdRet;
}

ssize_t recvMessageFromServer(int fd, char *buf, int bufLength) {
    train_t train;
    memset(buf, 0, bufLength);
    memset(&train, 0, sizeof(train));
    ssize_t recvRet = recv(fd, &train.length, sizeof(train.length), 0);
    ERROR_CHECK(recvRet, -1, "recv");
    recvRet = recv(fd, train.data, train.length, 0);
    ERROR_CHECK(recvRet, -1, "recv");
    memcpy(buf, train.data, train.length);
    return recvRet;
}
